from rest_framework import serializers
from .models import User, Supplier, DeliveryStaff

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'role', 'email', 'phone']
        read_only_fields = ['id']

class SupplierSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    class Meta:
        model = Supplier
        fields = ['id', 'user', 'company_name', 'business_license']
        read_only_fields = ['id']

class DeliveryStaffSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    user_id = serializers.IntegerField(write_only=True)

    class Meta:
        model = DeliveryStaff
        fields = ['id', 'user', 'user_id', 'vehicle_number', 'service_area']
        read_only_fields = ['id']

    def create(self, validated_data):
        user_id = validated_data.pop('user_id')
        try:
            user = User.objects.get(id=user_id)
            return DeliveryStaff.objects.create(user=user, **validated_data)
        except User.DoesNotExist:
            raise serializers.ValidationError({'user_id': '用户不存在'})

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField(write_only=True)

class RegisterSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    # 移除 role 字段，或将其设置为只读并提供默认值
    # 方案一：移除 role 字段，在 create 方法中固定角色
    class Meta:
        model = User
        fields = ['username', 'password', 'email', 'phone'] # 移除了 'role'

    def create(self, validated_data):
        password = validated_data.pop('password')
        # 强制设置角色为 'customer'
        user = User(**validated_data, role='customer') 
        user.set_password(password)
        user.save()
        return user

# 方案二：保留 role 字段但设为只读，并设置默认值 (如果模型层面已定义默认值，这里可以不设置)
# class Meta:
#     model = User
#     fields = ['username', 'password', 'role', 'email', 'phone']
#     read_only_fields = ['role'] # 将 role 设置为只读
#
# def create(self, validated_data):
#     password = validated_data.pop('password')
#     # 如果前端不应传递 role，确保 validated_data 中不包含 role，或在此处覆盖
#     validated_data['role'] = 'customer' # 强制设置角色
#     user = User(**validated_data)
#     user.set_password(password)
#     user.save()
#     return user

class ChangePasswordSerializer(serializers.Serializer):
    old_password = serializers.CharField(required=True)
    new_password = serializers.CharField(required=True)

    def validate_old_password(self, value):
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError("旧密码不正确。")
        return value

    def update(self, instance, validated_data):
        instance.set_password(validated_data['new_password'])
        instance.save()
        return instance

    # 由于我们是在更新现有用户 (instance)，而不是创建新用户，
    # 所以不需要 create 方法。 
    # 如果 .save() 时 instance 为 None (例如，如果这是一个创建操作的序列化器)，
    # 并且没有实现 create()，才会调用父类的 create() 导致 NotImplementedError。
    # 在我们的 change_password 视图中，我们总是会传递一个 instance (request.user)。
    # 因此，主要需要的是 update 方法。
    # 为了更清晰，可以显式地让 save 调用 update。
    def save(self, **kwargs):
        # 我们期望 instance (即 user 对象) 总是通过 context 传入，或者在调用 save 时传入
        # 在 UserViewSet 的 change_password action 中，我们调用 serializer.save() 时，
        # DRF 会将 request.user 作为 instance 传递给 update 方法。
        # 因此，这里的自定义 save 可能不是必需的，除非你想改变默认行为。
        # 但为了确保 update 被调用，我们可以这样做：
        assert hasattr(self, '_errors'), (
            'You must call `.is_valid()` before calling `.save()`.'
        )

        assert not self.errors, (
            'You cannot call `.save()` on a serializer with invalid data.'
        )
        
        # 我们期望 instance (user) 已经存在于 serializer 中
        # 通常，在视图中，你会这样做: serializer = ChangePasswordSerializer(request.user, data=request.data)
        # 或者，如果 instance 是通过 context 传递的，如 self.context['request'].user
        # 那么 DRF 的 save() 会自动处理。
        # 如果直接调用 serializer.save() 且 instance 不是通过构造函数传递的，
        # 那么需要确保 instance 在这里被正确设置。
        # 在我们的 UserViewSet 中，request.user 会被作为 instance 传递。
        self.instance = self.context['request'].user
        return self.update(self.instance, self.validated_data)